#ifndef Separator_H
#define Separator_H
#include <math.h>
#include <FFT\fft.h>
#include <FFT\Window.h>
#include <Helmholtz\Helmholtz.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define TWO_PI 6.28318530717958647692528676655900576
//#define Round(x) (int)((float)(x)+0.9999999999999)
#define MAX_FREQ 20000
class Harmonic{
	float *wincoff;

	float *fftReal;// Co Dinh
	float *fftImg;// Co Dinh

	float *DataSample;


	float ** hamonicChannel;

	float ** amplitudeChannel;

	float ** hamonicChannelCreated;

	float * noiseChannel;

	float * combinedHamonicsChannel;

	float * outputChannel;
	int HamonicNumber;
private:
	unsigned int SampleRate;
	unsigned int BlockSize;
	unsigned int BinPadding;
	unsigned int Overlap;
	float Frequency;
	float MaxFreq;
	unsigned int Length;
	float Band;

public:
	Harmonic(float *sample, unsigned int length, unsigned int overlap, unsigned int blocksize, unsigned int samplerate, unsigned int binpadding, float freq, float maxFreq, float bandFreq, int typewin = 0){

		Overlap = overlap;
		BlockSize = blocksize;
		SampleRate = samplerate;
		Band = bandFreq;
		BinPadding = ftob(Band / 2);//binpadding;
		//printf("BinPadding = %d\n", BinPadding);
		Frequency = freq;
		MaxFreq = maxFreq;
		HamonicNumber = 0;
		Length = length;

		fftReal = new float[BlockSize];
		fftImg = new float[BlockSize];

		wincoff = new float[BlockSize];

		hamonicChannel = NULL;
		noiseChannel = NULL;
		combinedHamonicsChannel = NULL;
		outputChannel = NULL;


		DataSample = new float[Length + BlockSize];

		memset(DataSample, 0, sizeof(float)*(Length + BlockSize));
		memcpy(&DataSample[BlockSize], sample, sizeof(float)* Length);

		initWin(typewin, BlockSize, wincoff);
	}
private:
	int ftob(float freq){
		return (int)(freq / ((float)this->SampleRate / (float)this->BlockSize));;
	}
	void initWin(int type, int size, float *coff){
		switch (type)
		{
		case Hanning:
			initDsp_winHan(size, coff);
			break;
		case Hamming:
			initDsp_winHam(size, coff);
			break;
		case BlackMan:
			initDsp_winBla(size, coff);
			break;
		default:
			break;
		}
		//for (int i = 0; i < blockSize; i++)
		//	wincoff[i] = 0.54 - 0.46 * cos((2.0*PI*i) / (blockSize - 1.0));;//0.5 * (1 - cos(2 * PI*i / (blockSize - 1)));
	}
	void processWin(float * sample){
		for (int i = 0; i < BlockSize; i++)
		{
			sample[i] *= wincoff[i];
		}
		//void print(float *data, int blockSize);
		//print(wincoff, BlockSize);

	}
	void processDeWin(float * sample){
		for (int i = 0; i < BlockSize; i++)
			sample[i] /= wincoff[i];
	}
	void normalizeAmplitude(float *data){
		for (int i = 0; i < BlockSize; i++){
			//printf("%5.5f   ", noiseFrame[i]);
			data[i] /= (float)BlockSize;
		}
	}
	void AvgOverlap(float *first, float *second){
		for (int i = 0; i < Overlap; i++){
			first[i] += second[i];
			//first[i] /= 2.0;
		}
	}
	void processFFTFrame(float * sample, int size){

		//sample = sample - Overlap * sizeof(float);
		float * tempReal = new float[BlockSize];
		float * tempImg = new float[BlockSize];

		float *dataReal = new float[BlockSize];

		memset(dataReal, 0, BlockSize * sizeof(float)); // Zero padding
		memcpy(dataReal, sample, size * sizeof(float));

		//processWin(dataReal);
		float *dataImg = new float[BlockSize];
		memset(dataImg, 0, BlockSize * sizeof(float));

		fft(dataReal, dataImg, BlockSize, tempReal, tempImg);
		//dataImg[0] = 0.0;
		//dataImg[BlockSize - 1] = 0.0;
		memcpy(fftReal, dataReal, BlockSize * sizeof(float));
		memcpy(fftImg, dataImg, BlockSize * sizeof(float));

		delete[]dataReal;
		delete[]dataImg;

		delete[]tempReal;
		delete[]tempImg;


	}
	float *GetHamonicFrame(float freq){
		float * hamonic = new float[BlockSize];

		float * harmoReal = new float[BlockSize];;
		float * harmoImg = new float[BlockSize];;

		memset(harmoReal, 0, BlockSize * sizeof(float));
		memset(harmoImg, 0, BlockSize * sizeof(float));

		float * tempReal = new float[BlockSize];
		float * tempImg = new float[BlockSize];


		unsigned int bin = ftob(freq);
		if (bin <= BlockSize / 2){
			int binstart = bin - BinPadding;
			int binend = bin + BinPadding;
			//if (binstart <= bin  && bin <= binend)
			//printf("bin Start End %d %d \n", binstart, binend);
			for (int bin = binstart; bin <= binend; bin++)
			{

				//if CURRENT_BIN is within bin padding for freq and freq is not above maxFreq, send to harmonics channel
				harmoReal[bin] = fftReal[bin];
				harmoImg[bin] = fftImg[bin];

				harmoReal[BlockSize - 1 - bin] = fftReal[BlockSize - 1 - bin];
				harmoImg[BlockSize - 1 - bin] = fftImg[BlockSize - 1 - bin];

			}


			/*memcpy(&harmoReal[bin - BinPadding ], &fftReal[bin - BinPadding], (1 + (BinPadding)* 2)* sizeof(float));
			memcpy(&harmoImg[bin - BinPadding ], &fftImg[bin - BinPadding], (1 + (BinPadding)* 2)* sizeof(float));
			print(harmoReal, BlockSize);
			memcpy(&harmoReal[BlockSize - 1 - (bin - BinPadding)], &fftReal[BlockSize - 1 - (bin - BinPadding)], (1 + (BinPadding)* 2)* sizeof(float));
			memcpy(&harmoImg[BlockSize - 1 - (bin - BinPadding)], &fftImg[BlockSize - 1 - (bin - BinPadding)], (1 + (BinPadding)* 2)* sizeof(float));
			*/
			//print(harmoReal, BlockSize);
			ifft(harmoReal, harmoImg, BlockSize, tempReal, tempImg);
			memcpy(hamonic, harmoReal, BlockSize * sizeof(float));
			normalizeAmplitude(hamonic);

			//print(hamonic, BlockSize);

		}
		else{
			printf("Frequency So large \n");
		}

		delete[] tempReal;
		delete[] tempImg;
		delete[] harmoReal;
		delete[] harmoImg;


		return hamonic;
	}


	void processData(){

		int ll = 1;
		unsigned int harmonic = MaxFreq / Frequency + 1;
		printf("Max freq %5.5f - Freq %5.5f\n", MaxFreq, Frequency);
		hamonicChannel = (float**)malloc(harmonic * sizeof(float*));

		unsigned int i = 0;

		float curr_freq = ((i + 1) * Frequency);
		while (curr_freq < MaxFreq){

			printf("Processing %d harmonic at freq = %5.5f\n", i + 1, curr_freq);
			float *current_harmonic_channel = hamonicChannel[i] = new float[Length];
			memset(current_harmonic_channel, 0, Length*sizeof(float));

			float* tmp_channel = new float[Length + BlockSize];
			memset(tmp_channel, 0, (Length + BlockSize)*sizeof(float));
			for (unsigned int blockStart = 0; blockStart < Length + BlockSize; blockStart += BlockSize - Overlap)
			{
				unsigned int numSamplesInBlock = BlockSize;

				if (blockStart + BlockSize > Length + BlockSize)
					numSamplesInBlock = Length + BlockSize - blockStart;
				unsigned int lap = 0;
				if (blockStart != 0){
					lap = Overlap;
				}
				if (numSamplesInBlock)
				{

					processFFTFrame(&DataSample[blockStart], numSamplesInBlock); // FFT Frame store to fft i/m

					if (hamonicChannel/* && numSamplesInBlock == BlockSize*/ /*&& ll < 2*/){
						float * current_frame = this->GetHamonicFrame(curr_freq);
						processWin(current_frame);
						//fir_bandpass(current_frame, wincoff, curr_freq - Band / 2, curr_freq + Band / 2);
						//memcpy(current_harmonic_channel + blockStart , current_frame + lap, (numSamplesInBlock - lap)*sizeof(float));
						//AvgOverlap(current_harmonic_channel + blockStart -  lap, current_frame);
						//delete[]current_frame;
						unsigned int ind_frame = 0;
						//printf("Start  %d End %d ", blockStart, blockStart + numSamplesInBlock);
						for (unsigned int ind = blockStart; ind < blockStart + Overlap && ind < Length + BlockSize; ind++){

							tmp_channel[ind] += current_frame[ind_frame];
							//current_harmonic_channel[ind] /= 2.0;
							ind_frame++;
						}

						for (unsigned int ind = blockStart + Overlap; ind < blockStart + numSamplesInBlock && ind < Length + BlockSize; ind++){

							tmp_channel[ind] += current_frame[ind_frame];
							ind_frame++;
						}

						delete[] current_frame;
					}

					ll++;
				}

			}

			memcpy(current_harmonic_channel, &tmp_channel[BlockSize], Length * sizeof(float));
			delete[] tmp_channel;
			i++;
			curr_freq = ((i + 1) * Frequency);
			}
			HamonicNumber = i ;
		}


	float *GetNoiseFrame(){
		float * noise = new float[BlockSize];

		float * noiseReal = new float[BlockSize];;
		float * noiseImg = new float[BlockSize];;

		memcpy(noiseReal, fftReal, BlockSize *sizeof(float));
		memcpy(noiseImg, fftImg, BlockSize *sizeof(float));
		float * tempReal = new float[BlockSize];
		float * tempImg = new float[BlockSize];

		for (unsigned int i = 0; i < HamonicNumber; i++){
			int bin = ftob(Frequency * (i + 1));
			if (bin <= BlockSize / 2){
				unsigned int binstart = bin - BinPadding;
				unsigned int binend = bin + BinPadding;
				for (unsigned int bin = binstart; bin <= binend; bin++)
				{

					//if CURRENT_BIN is within bin padding for freq and freq is not above maxFreq, send to harmonics channel
					noiseReal[bin] = 0;
					noiseImg[bin] = 0;

					noiseReal[BlockSize - 1 - bin] = 0;
					noiseImg[BlockSize - 1 - bin] = 0;

				}

			}
			else{
				printf("Frequency So large \n");
			}
		}

		ifft(noiseReal, noiseImg, BlockSize, tempReal, tempImg);
		memcpy(noise, noiseReal, BlockSize * sizeof(float));
		normalizeAmplitude(noise);

		delete[] tempReal;
		delete[] tempImg;
		delete[] noiseImg;
		delete[] noiseReal;


		return noise;
	}


	void processNoise(){
		

		float *tmp_noise = new float[Length + BlockSize];
		memset(tmp_noise, 0, (Length + BlockSize)*sizeof(float));

		for (unsigned int blockStart = 0; blockStart < Length + BlockSize; blockStart += BlockSize - Overlap)
		{
			unsigned int numSamplesInBlock = BlockSize;

			if (blockStart + BlockSize > Length + BlockSize)
				numSamplesInBlock = Length + BlockSize - blockStart;
			unsigned int lap = 0;
			if (blockStart != 0){
				lap = Overlap;
			}
			if (numSamplesInBlock)
			{

				processFFTFrame(&DataSample[blockStart], numSamplesInBlock); // FFT Frame store to fft i/m

				float * current_frame = this->GetNoiseFrame();
				processWin(current_frame);
				unsigned int ind_frame = 0;
				for (int ind = blockStart; ind < blockStart + Overlap && ind < Length + BlockSize; ind++){

					tmp_noise[ind] += current_frame[ind_frame];
					//current_harmonic_channel[ind] /= 2.0;
					ind_frame++;
				}

				for (unsigned int ind = blockStart + Overlap; ind < blockStart + numSamplesInBlock && ind < Length + BlockSize; ind++){

					tmp_noise[ind] += current_frame[ind_frame];
					ind_frame++;
				}

				delete[] current_frame;
			}

		}

		noiseChannel = new float[Length ];
		memcpy(noiseChannel, &tmp_noise[BlockSize], sizeof(float)* Length);

		delete[] tmp_noise;
	}
	


	float *createAmplitudeHarmonic(float * harnomic, float* result){
		float *amplitude_channel = result;//new float[Length];
		memset(amplitude_channel, 0, sizeof(float)* Length);
		int up_flag = 1;
		int begTred = 0;
		int endTred = 0;

		float  begamplitude = 0;
		float endamplitude = 0;
		for (int i = 0; i < Length - 1; i++){
			{
				if (harnomic[i] > harnomic[i - 1]){ //Up
					if (up_flag == -1){ // Down
						begTred = endTred;
						endTred = i;
						begamplitude = endamplitude;
						endamplitude = abs(harnomic[i]);
						//printf("beg %f end %f \n", begamplitude, endamplitude);
						float k = (endamplitude - begamplitude) / (endTred - begTred);
						//printf("%f \n", k);
						for (int beg = begTred; beg < endTred; beg++){
							if (begTred != 0)
								amplitude_channel[beg] = begamplitude + k* (beg - begTred);
							else
								amplitude_channel[beg] = endamplitude;
						}
					}

					up_flag = 1;
				}
				else if (harnomic[i] < harnomic[i - 1]){ //dOWN
					if (up_flag == 1){ // up
						begTred = endTred;
						endTred = i;
						begamplitude = endamplitude;
						endamplitude = abs(harnomic[i]);
						//printf("beg %f end %f \n", begamplitude, endamplitude);
						float k = (endamplitude - begamplitude) / (endTred - begTred);
						//printf("%f \n", k);
						for (int beg = begTred; beg < endTred; beg++){
							if (begTred != 0)
								amplitude_channel[beg] = begamplitude + k* (beg - begTred);
							else
								amplitude_channel[beg] = endamplitude;
						}
					}
					up_flag = -1;
				}
				else
				{
					up_flag = 0;
				}
			}
		}
		return amplitude_channel;
	}

	float *rereateSinwave(float * harnomic, float *amplitudeHarmonic, int index, float *&result){
		float *amplitude_channel = result;//new float[Length];
		memset(amplitude_channel, 0, sizeof(float)* Length);

		float curr_freq = (index + 1)*Frequency;
		printf("Create Sinwave %d at Freq = %f\n", index + 1, curr_freq);

		extern float RandDomPhaseList[];

		//double phase = 0.0;
		//double phase = TWO_PI/4.0;
		double phase = RandDomPhaseList[index] * TWO_PI / 2.; 
		//double phase = asinf(harnomic[0]);

		float incPhase = ((1.f /(float) SampleRate) * curr_freq) *TWO_PI;


		printf("incPhase %2.10f   frequency %2.10f  Sample %d\n", incPhase, curr_freq, SampleRate);

		for (unsigned int j = 0; j < Length; j++){

			amplitude_channel[j] = sinf(phase) * amplitudeHarmonic[j];
			phase += incPhase;

		}
		return amplitude_channel;
	}

	void combineWave(float * combineChannel){
		printf("Combine All RecreateSinwave \n");
		memset(combineChannel, 0, sizeof(float)*Length);
		for (unsigned int j = 0; j < Length; j++){
			for (unsigned int i = 0; i < HamonicNumber; i++){
				float *curr_reatedchannel = hamonicChannelCreated[i];
				combineChannel[j] += curr_reatedchannel[j];
				//printf("Har %d curr_reatedchannel[%d][%d]  = %f \n", i, i, j, curr_reatedchannel[j]);
			}
			//printf("%d   Combine %f\n", j, noiseChannel[j], combineChannel[j]);
		}
	}

	void combineWaveNoise( float * result){
		printf("Combine All RecreateSinwave  With Noise\n");
			for (unsigned int j = 0; j < Length; j++){
				result[j] = noiseChannel[j] + combinedHamonicsChannel[j];
			//printf("%d  Noise %f  Combine %f\n", j, noiseChannel[j], combineChannel[j]);
			}
		}

	void createHarmonic(){
		processData();
		amplitudeChannel = (float **)malloc(HamonicNumber * sizeof(float *));
		hamonicChannelCreated = (float **)malloc(HamonicNumber * sizeof(float *));

		for (unsigned int i = 0; i < HamonicNumber; i++){

			float * curr_harmonic = hamonicChannel[i];

			//Amplitude
			printf("Get Amplitude  Channel %d\n", i + 1);
			float * curr_amplitude = amplitudeChannel[i] = new float[Length];
			/*float * amplitude_tmp = */createAmplitudeHarmonic(curr_harmonic, curr_amplitude);
			//memcpy(curr_amplitude, amplitude_tmp, Length*sizeof(float));
			//delete[] amplitude_tmp;

			//Recreate Sinwave
			printf("Get Recreate Sinwave  Channel %d\n", i + 1);
			float * curr_channel = hamonicChannelCreated[i] = new float[Length];
			/*float * sinwave_tmp =*/ rereateSinwave(curr_harmonic,curr_amplitude, i, curr_channel);
			//memcpy(curr_channel, sinwave_tmp, Length*sizeof(float));
			//delete[] sinwave_tmp;

		}



	}

public:
	void processChannel(){
		printf("Create each Harmonic\n");
		createHarmonic();// Create Harmonnic , Amplitude channel, hamonicChannelCreated

		printf("Create Combined Harmonics\n");
		combinedHamonicsChannel = new float[Length];
		combineWave(combinedHamonicsChannel); // Summary all recreated harmonics

		printf("Create Noise Channel \n");
		processNoise();

		outputChannel = new float[Length];
		printf("Create Output Channel\n");
		combineWaveNoise(outputChannel);// Get output Summary combinewave and noise.


	}


	int getHarmonicNumber(){
		return HamonicNumber;
	}


	float *getHarmonicChannels(int index){
		return hamonicChannel[index - 1];
	}
	float *getAmplitudeChannel(int index){
		return amplitudeChannel[index - 1];
	}
	float *getHamonicChannelCreated(int index){
		return hamonicChannelCreated[index - 1];
	}

	float *getNoiseChannel(){
		return noiseChannel;
	}

	float *getcombinedChannel(){
		return combinedHamonicsChannel;
	}

	float *getoutputChannel(){
		return outputChannel;
	}


	~Harmonic(){
		if (fftReal) delete[] fftReal;
		if (fftImg) delete[] fftImg;
		if (wincoff) delete wincoff;
		if (DataSample) delete[] DataSample;
		if (noiseChannel) delete[] noiseChannel;
		if (outputChannel) delete[] outputChannel;
		if (combinedHamonicsChannel) delete[] combinedHamonicsChannel;
		for (int i = 0; i < HamonicNumber; i++){
			delete hamonicChannel[i];
			delete amplitudeChannel[i];
			delete hamonicChannelCreated[i];
			}
		
		delete[] hamonicChannel;
		delete[] amplitudeChannel;
		delete[] hamonicChannelCreated;
	}
private:
	int fir_bandpass(float *h, float *w, float fc1, float fc2)
	{
		int i, j;
		int delay;
		int N = BlockSize;

		//assert(N & 1);
		delay = (N) / 2;

		for (i = 0, j = N - 1; i <= delay; i++, j--) {
			h[i] = ((float)fc2*sinf(fc2*(i - delay)) - (float)fc1*sinf(fc1*(i - delay)))* w[i];
			h[j] = h[i];
		}

		h[delay] = fc2 - fc1;

		return N;

	}
	};




/*
class Separator{
private:
	float *wincoff;

	float *fftReal;// Co Dinh
	float *fftImg;// Co Dinh
	float *spectrum;

	float *tempReal;// Co Dinh
	float *tempImg; // Co Dinh

	float *noiseReal;// Co Dinh
	float *noiseImg;// Co Dinh

	float *harmonicReal;// Co Dinh
	float *harmonicImg;// Co Dinh

	float *noiseFrame;// Co Dinh
	float *harmonicFrame;// Co Dinh


	float *frequencyHarmonic;
	float *resynthesis;
	float percent;
	float *phase;
private:
	int blockSize;
	int samplerate;
	float maxFreq;
	int binPadding;
	int count;
	int size;
	int overlap;
	int time;
	float freq;
	float initFreq;
	float * hhout;
	Helmholtz *helmholtz ;
	float HelFidelity;
	float hold_freq;
public:
	Separator(int blockSize, int overlap, int samplerate, float initFreq, float HelFidelity, float maxFreq, float bankfreq, int typewin = 0) {
		this->blockSize = blockSize;
		this->initFreq = initFreq;
		this->samplerate = samplerate;
		this->hhout = new float[blockSize];;
		this->HelFidelity = HelFidelity;
		this->wincoff = new float[blockSize];
		this->initWin(typewin);
		this->frequencyHarmonic = NULL;
		//print(wincoff);

		this->overlap = overlap;
		this->maxFreq = maxFreq;
		this->resynthesis = new float[blockSize];
		this->phase = new float[blockSize];
		memset(phase, 0, blockSize * sizeof(float));

		fftReal = new float[blockSize];
		fftImg = new float[blockSize];

		this->binPadding = 4;//ftob(bankfreq);
		memset(fftReal, 0, blockSize * sizeof(float));
		memset(fftImg, 0, blockSize * sizeof(float));

		tempReal = new float[blockSize];
		tempImg = new float[blockSize];


		noiseReal = new float[blockSize];
		noiseImg = new float[blockSize];
		harmonicReal = new float[blockSize];
		harmonicImg = new float[blockSize];

		noiseFrame = new float[blockSize];
		harmonicFrame = new float[blockSize];

		spectrum = new float[blockSize];
		helmholtz = new Helmholtz(blockSize, overlap);
		count = 0;
		time = 0;
	}
	int ftob(float freq){
		return (int)(freq / ((float)this->samplerate / (float)this->blockSize));;
	}
	void initWin(int type){
		switch (type)
		{
		case Hanning:
			initDsp_winHan(blockSize, wincoff);
			break;
		case Hamming:
			initDsp_winHam(blockSize, wincoff);
			break;
		case BlackMan:
			//initDsp_winBla(blockSize, wincoff);
			break;
		default:
			break;
		}
		//for (int i = 0; i < blockSize; i++)
		//	wincoff[i] = 0.54 - 0.46 * cos((2.0*PI*i) / (blockSize - 1.0));;//0.5 * (1 - cos(2 * PI*i / (blockSize - 1)));
	}

	void processWin(float * sample){
		for (int i = 0; i < blockSize; i++)
			sample[i] *=wincoff[i];
	}
	void processDeWin(float * sample){
		for (int i = 0; i < blockSize; i++){
			
				sample[i] /= wincoff[i];
				//sample[i] *= (2. / 3.) / blockSize;
		}

	}
	void processFFTFrame(float * sample, int size, float freq);
	void separatorFrame(float freq);
	void processIFFTFrame();
	void normalizeAmplitude( float *data){
		for (int i = 0; i < blockSize; i++){
			//printf("%5.5f   ", noiseFrame[i]);
			data[i] /= (float)blockSize;
			//printf("   %2.5f \n", noiseFrame[i]);
		}
	}
	void processBlock(float * sample, int size);
	void SumOverlap(float *first, float *second, int overlap);
	float * getNoise(){
		/*if (time){
			return noiseFrame +overlap / 2;
	}
		else{
			return noiseFrame ;
			}*/ /*
		return noiseFrame;
	}

	float * getHarmonic(){
		/*if (time){
			return resynthesis + overlap / 2;
		}
		else{
			return resynthesis;
		}
		return resynthesis;
	}

	void processData(int length, float * sample, float * noiseChannel, float * hamonicChannel);

	void processSpectrum(float *sample, int size_);

	void ResynthesisHamolet(float freq);

	float *  getSpectrum(){
		return spectrum;
	}
	float *GetHamonicFrame(float freq);
	~Separator(){
		if (fftReal) delete[] fftReal;
		if (fftImg) delete[] fftImg;
		if (spectrum) delete[] spectrum;
		if (tempReal) delete[] tempReal;
		if (tempImg) delete[] tempImg;
		if (noiseReal) delete[] noiseReal;
		if (noiseImg) delete[] noiseImg;
		if (harmonicReal) delete[] harmonicReal;
		if (harmonicImg) delete[] harmonicImg;
		if (noiseFrame) delete[] noiseFrame;
		if (harmonicFrame) delete[] harmonicFrame;
		if (frequencyHarmonic) delete[] frequencyHarmonic;
		if (resynthesis) delete[]resynthesis;
		if (phase) delete phase;
		if (wincoff) delete wincoff;
		if (helmholtz) delete helmholtz;
	}


	void print(float *data){
		for (int i = 0; i < blockSize; i++){
			if (data[i] != 0.0)
				printf("bin = %d  %.10f  \n ",i, data[i]);
			else
				printf("bin = %d  F*****   \n",i);
			if (!i % 4){
				printf("\n");
			}
		}
			
	}
};

*/


#endif // #ifndef Separator_H